using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using MotaWeb.Security;
using System.Web.Security;
using MotaWeb.Models.Interfaces;
using MotaWeb.Models;

namespace MotaWeb.Controllers
{
    public class AdminController : MotaControllerBase
    {
        public AdminController()
            : this(null, null)
        {
        }

        public AdminController(IMembershipService memberships, IRoleService roles)
        {
            MembershipService = memberships ?? new AccountMembershipService();
            RoleService = roles ?? new RoleMembershipService();
        }

        public IMembershipService MembershipService
        {
            get;
            private set;
        }

        public IRoleService RoleService
        {
            get;
            private set;
        }

        //
        // GET: /Admin/

        public ActionResult Index()
        {
            return View();
        }

        [Authorize(Roles = "Administrator")]
        public ActionResult Users()
        {
            return View(this.GetSiteUsers());
        }


        //
        // GET: /Biography/EditUser/userName
        [Authorize(Roles = "Member, Administrator")]
        public ActionResult EditUser(string userName)
        {
            if (!UserCanEditUserName(userName))
                ModelState.AddModelError("Authorization", "You are not authorized to edit this user's information");

            if (!ModelState.IsValid)
            {
                return RedirectToAction("Index", "Home");
            }

            ViewData["SelectedRoles"] = GetRolesList(RoleService.GetRolesForUser(userName));
            return View(this.GetSiteUser(userName));
        }

        //
        // POST: /Biography/EditUser/userName
        [Authorize(Roles = "Member, Administrator")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditUser(string userName, FormCollection collection)
        {
            if (!UserCanEditUserName(userName))
                ModelState.AddModelError("Authorization", "You are not authorized to edit this user's information");

            if (!ModelState.IsValid)
            {
                return View();
            }
            try
            {
                ISiteUser user = this.GetSiteUser(userName);
                user.FirstName = collection["FirstName"];
                user.LastName = collection["LastName"];
                user.Email = collection["Email"];
                user.Roles = BuildRolesArray(collection["Roles"]);

                MembershipService.UpdateUser(user);

                AddNewRolesToUser(user);
                Repository.UpdateSiteUser(user);

                if (User.IsInRole("Administrator"))
                    return RedirectToAction("Users");
                else
                    return RedirectToAction("Index", "Home");
            }
            catch (Exception)
            {
                return View();
            }
        }


        #region Private Methods 
        private bool UserCanEditUserName(string userName)
        {
            return User.IsInRole("Administrator") || User.Identity.Name == userName;
        }

        private List<ISiteUser> GetSiteUsers()
        {
            var siteUsers = new List<ISiteUser>();
            MembershipUserCollection users = MembershipService.GetAllUsers();
            foreach (MembershipUser user in users)
            {
                ISiteUser siteUser = Repository.SiteUserFromMembershipUser(user);
                siteUser.Roles = RoleService.GetRolesForUser(siteUser.UserName);
                siteUsers.Add(siteUser);
            }
            return siteUsers;
        }


        private ISiteUser GetSiteUser(string userName)
        {
            MembershipUser user = MembershipService.GetUser(userName);
            ISiteUser siteUser = Repository.SiteUserFromMembershipUser(user);
            siteUser.Roles = RoleService.GetRolesForUser(userName);
            siteUser.Email = user.Email;
            return siteUser;
        }

        private bool RolesAreValid(string roles)
        {
            bool areValid = true;

            string[] roleCollection = BuildRolesArray(roles);
            foreach (string role in roleCollection)
            {
                if (RoleService.RoleExists(role))
                {
                    areValid = false;
                    break;
                }
            }
            return areValid;
        }

        private static string[] BuildRolesArray(string roles)
        {
            string[] roleCollection = new string[] { roles };
            if (roles.IndexOf(',') > 0)
            {
                roleCollection = roles.Split(',');
            }
            return roleCollection;
        }

        private void AddNewRolesToUser(ISiteUser user)
        {
            List<string> newRoles = new List<string>();
            foreach (var r in user.Roles)
            {
                if (!Roles.IsUserInRole(user.UserName, r))
                    newRoles.Add(r);
            }

            if(newRoles.Count > 0)
                Roles.AddUserToRoles(user.UserName, newRoles.ToArray());
        }


        private MultiSelectList GetRolesList(string[] selectRoles)
        {
            return new MultiSelectList(RoleService.GetAllRoles(), selectRoles);
        }
        #endregion
    }
}
